package merisis.traitspace.impl;

import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import merisis.traitspace.History;
import merisis.util.BitUtil;

import org.apache.solr.util.OpenBitSet;


import com.google.inject.Inject;

public class MemoryHistoryImpl implements History {

	@Inject
	private Logger logger;

	private Map<Long, OpenBitSet> mapByElement = new HashMap<Long, OpenBitSet>();

	private Map<Long, OpenBitSet> mapByCategory = new HashMap<Long, OpenBitSet>();

	public void emerge(long from, long to) {
		
		if (from == to)
			throw new IllegalArgumentException("cyclic! "  + from);

		synchronized (this) {
			setGroup(mapByElement, to, from);
			setGroup(mapByCategory, from, to);
		}

		if (logger.isLoggable(Level.FINEST))
			logger.finest(String.format("recorded, %d --> %d", from, to));
	}

	public void erase(long from, long to) {

		unsetGroup(mapByElement, to, from);
		unsetGroup(mapByCategory, from, to);
	}

	public long[] next(long initial) {
		
		OpenBitSet s = mapByCategory.get(initial);
		
		return BitUtil.toArray(s);
	}

	public long[] previous(long node) {

		OpenBitSet s = mapByElement.get(node);
		
		return BitUtil.toArray(s);
	}

	private void setGroup(Map<Long, OpenBitSet> map, long key, long value) {

		OpenBitSet group = map.get(key);
		if (group == null) {

			group = new OpenBitSet();
			map.put(key, group);
		}
		group.set(value);
	}

	private void unsetGroup(Map<Long, OpenBitSet> map, long key, long value) {

		OpenBitSet group = mapByCategory.get(key);
		if (group == null)
			return;

		group.clear(value);
	}

	public int entropy(long event) {
		// TODO Auto-generated method stub
		return 0;
	}
}
